package rothag.views.gamestep.diceshot;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import rothag.models.Joueur;
import rothag.controller.MainController;
import rothag.enums.TypeDes;
import rothag.graphics.*;
import rothag.views.*;
import rothag.views.gamestep.GameStepJPanelBase;
import rothag.listener.DesListener;

/**
 *
 * @author Gaetan, Gulian
 */
public class LancerDesJPanel extends GameStepJPanelBase implements MouseListener, ActionListener, DesListener {

    private JButtonBase lancerDes;
    private JButtonBase etapeSuivante;
    private ArrayList<DeJLabel> listeDesTires;
    private ArrayList<DeJLabel> listeDesSelectionnes;
    private int startXTires;
    private int startYTires;
    private int startXSels;
    private int startYSels;
    private int espaceDes;
    private int nbDesLigne = 4;
    private int nbLances;
    private int mouseLastY;
    private int mouseLastX;

    public LancerDesJPanel(MainController controller) {
        super(controller);

        controller.addDesListener(this);

        // Légende des dés
        int xLegende = 500;
        int yLegende = 70;
        int espaceLegende = 5;
        int hauteurLabel = 20;

        Font font = GraphicsHelper.getFont(13, "bold");
        JLabel label = new JLabel("Légende :");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, 15);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        ImageIcon icon = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesLegende, this);
        if (icon.getIconWidth() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesLegende, this).setVisible(true);
            System.exit(1);
        }
        label = new JLabel(icon);
        label.setBounds(xLegende, yLegende, 45, 254);
        add(label);

        xLegende += label.getWidth() + espaceLegende;

        espaceLegende = 2;
        yLegende += espaceLegende;

        font = GraphicsHelper.getFont(13, null);

        label = new JLabel("3 Ouvriers");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        label = new JLabel("1 Ressource");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        label = new JLabel("<html>1 Catastrophe et<br>2 Ressources</html>");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        label = new JLabel("3 Nourritures");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        label = new JLabel("<html>2 Nourritures ou<br>2 Ouvriers</html>");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        yLegende += label.getHeight() + espaceLegende;

        label = new JLabel("7 Pièces d'or");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(xLegende, yLegende, largeur - xLegende, hauteurLabel * 2);
        add(label);

        // Instructions
        label = new JLabel("Pour garder un des dés tirés, faites le glisser dans la zone ci-dessous.");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(50, GraphicsParameters.bigFrameBottomY - hauteurLabel, largeur - 250, hauteurLabel);
        add(label);

        label = new JLabel("Dés gardés : ");
        label.setFont(font);
        label.setForeground(Color.white);
        label.setBounds(50, GraphicsParameters.smallFrameTopY, largeur - 250, hauteurLabel);
        add(label);

        // Boutons
        lancerDes = new JButtonBase("Lancer les dès");
        lancerDes.setBounds(550, GraphicsParameters.bigFrameBottomY - 60, 120, 40);
        lancerDes.addActionListener(this);
        add(lancerDes);

        etapeSuivante = new JButtonBase("Etape suivante");
        etapeSuivante.setBounds(550, GraphicsParameters.smallFrameTopY + 60, 120, 40);
        etapeSuivante.addActionListener(this);
        add(etapeSuivante);

        // Des
        startXTires = 60;
        startYTires = 60;
        startXSels = 60;
        startYSels = GraphicsParameters.smallFrameTopY + 40;
        espaceDes = 5;
    }

    public void reset() {
        nbLances = controller.lancerDes();

        listeDesTires = new ArrayList<DeJLabel>();
        listeDesSelectionnes = new ArrayList<DeJLabel>();

        repaintDes(false);
    }

    public void repaintDes(boolean anim) {
        int x = startXTires;
        int y = startYTires;
        int i = 0;

        // Suppression des dés
        for (Component c : getComponents()) {
            if (c instanceof DeJLabel) {
                remove(c);
            }
        }

        if (listeDesTires != null) {

            for (DeJLabel de : listeDesTires) {
                if (anim) {
                    de.setBounds(x, y, 0, 0);
                    add(de);

                    Timer timer = new Timer();
                    timer.schedule(new ZoomOut(de), 0, 5);
                } else {
                    de.setBounds(x, y, de.getImage().getIconWidth(), de.getImage().getIconHeight());
                    add(de);
                }

                i++;

                if (i % nbDesLigne == 0) {
                    y += de.getImage().getIconHeight() + espaceDes;
                    x = startXTires;
                } else {
                    x += de.getImage().getIconWidth() + espaceDes;
                }
            }
        }

        if (listeDesSelectionnes != null) {
            x = startXSels;
            y = startYSels;

            for (DeJLabel de : listeDesSelectionnes) {
                de.setBounds(x, y, de.getImage().getIconWidth(), de.getImage().getIconHeight());
                add(de);

                x += de.getBounds().getWidth() + espaceDes;
            }
        }

        repaint();
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {

        if (e.getSource() instanceof DeJLabel) {
            mouseLastX = e.getX();
            mouseLastY = e.getY();

            DeJLabel de = (DeJLabel) e.getSource();
            Image img = de.getImage().getImage();

            Cursor monCurseur = getToolkit().createCustomCursor(img, new Point(e.getX(), e.getY()), "DE");
            setCursor(monCurseur);
        }

    }

    public void mouseReleased(MouseEvent e) {
        setCursor(Cursor.getDefaultCursor());

        if (e.getSource() instanceof DeJLabel) {

            DeJLabel label = (DeJLabel) e.getSource();

            if (listeDesTires.contains(label)) {
                if ((mouseLastX == e.getX() && mouseLastY == e.getY()) || e.getY() > GraphicsParameters.bigFrameBottomY - startYTires) {
                    listeDesTires.remove(label);
                    controller.selectionnerDes(label.getTypeDe());
                }
                label.setBorder(null);
            } else {
                if ((mouseLastX == e.getX() && mouseLastY == e.getY()) || e.getY() + startYSels < GraphicsParameters.smallFrameTopY) {
                    if (controller.deselectionnerDes(label.getTypeDe())) {
                        listeDesTires.add(label);
                    }
                }
                label.setBorder(null);
            }

            repaintDes(false);
        }

    }

    public void mouseEntered(MouseEvent e) {
        if (e.getSource() instanceof DeJLabel) {
            DeJLabel label = (DeJLabel) e.getSource();
            label.setBorder(new DeBorder());
            label.repaint();
        }
    }

    public void mouseExited(MouseEvent e) {
        if (e.getSource() instanceof DeJLabel) {
            DeJLabel label = (DeJLabel) e.getSource();
            label.setBorder(null);
            label.repaint();
        }
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == etapeSuivante) {
            int nbVilles = controller.getNbVilleJoueurCourant();

            if (nbVilles == listeDesSelectionnes.size()) {
                controller.etapeSuivante();
            } else {
                GraphicsHelper.afficherErreur("Sélection des dés", "Vous devez sélectionner " + nbVilles + " dés.", this).setVisible(true);
            }
        } else if (e.getSource() == lancerDes) {
            if (listeDesTires.size() > 0 || listeDesSelectionnes.isEmpty()) {
                ArrayList<TypeDes> listeDes = controller.genereDes();
                listeDesTires.clear();

                for (TypeDes des : listeDes) {
                    DeJLabel label = new DeJLabel(des);
                    label.addMouseListener(this);
                    listeDesTires.add(label);
                }

                repaintDes(true);
            }
        }

    }

    public void joueurCourantChanged(Joueur joueurCourant) {
    }

    public void desGardesChanged(ArrayList<TypeDes> listeDes) {
        if (listeDesSelectionnes == null) {
            listeDesSelectionnes = new ArrayList<DeJLabel>();
        }
        listeDesSelectionnes.clear();

        for (TypeDes des : listeDes) {
            DeJLabel label = new DeJLabel(des);
            label.addMouseListener(this);
            listeDesSelectionnes.add(label);
        }

        repaintDes(false);
    }

    private class ZoomOut extends TimerTask {

        private DeJLabel de;

        public ZoomOut(DeJLabel de) {
            this.de = de;
        }

        @Override
        public void run() {
            boolean modif = false;
            if (de.getBounds().getHeight() < de.getImage().getIconHeight()) {
                de.setBounds((int) de.getBounds().getX(), (int) de.getBounds().getY(), (int) de.getBounds().getWidth(), (int) de.getBounds().getHeight() + 1);
                modif = true;
            }
            if (de.getBounds().getWidth() < de.getImage().getIconWidth()) {
                de.setBounds((int) de.getBounds().getX(), (int) de.getBounds().getY(), (int) de.getBounds().getWidth() + 1, (int) de.getBounds().getHeight());
                modif = true;
            }

            if (!modif) {
                this.cancel();
            }

        }
    }
}
